'''
基于select de IO多路复用并发模型
重点代码

目标:服务端能够同时应对多个客户端发消息和连接
思路:将监听套接字与连接套接字一起监控
'''
from socket import *
from select import select

HOST = '0.0.0.0'
PORT = 1210
ADDR = (HOST, PORT)

rlist = []
wlist = []
xlist = []


# 处理客户端连接
def connect_client(sock):
    connfd, addr = sock.accept()
    print('Connect from', addr)
    connfd.setblocking(False)
    rlist.append(connfd)


# 客户端发送连接
def handle(connfd):
    data = connfd.recv(1024)
    if not data:
        rlist.remove(connfd)  # 从监控列表删除
        connfd.close()
        return  # 继续处理下一个IO
    print(data.decode())
    connfd.send(b'ok')


# 启动服务函数
def main():
    # 创建监听套接字
    sock = socket()
    sock.bind(ADDR)
    sock.listen(5)
    sock.setblocking(False)
    print('Listen the port %d' % PORT)

    rlist.append(sock)  # 初始关注监听套接字

    # 循环接受监控IO发生
    while True:
        rs, ws, xs = select(rlist, wlist, xlist)
        for r in rs:
            if r is sock:
                connect_client(r)
            else:
                handle(r)
                # wlist.append(r)
        # for w in ws:
        #     w.send(b'ok')
        #     wlist.remove(w)


if __name__ == '__main__':
    main()
